package com.fengwk.support.util;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.fengwk.support.exception.BaseException;

/**
 * 类型工具
 */
public final class TypeUtils {	
	
	private static final Class<Object> CLASS_OBJECT = Object.class;
	
	private final static Class<Boolean> CLASS_BOOLEAN = Boolean.class;
	
	@SuppressWarnings("rawtypes")
	private final static Class<Collection> CLASS_COLLECTION = Collection.class;
	
	@SuppressWarnings("rawtypes")
	private final static Class<Set> CLASS_SET = Set.class;
	
	@SuppressWarnings("rawtypes")
	private final static Class<List> CLASS_LIST = List.class;
	
	@SuppressWarnings("rawtypes")
	private final static Class<Map> CLASS_MAP = Map.class;

	// 基本类型
    private final static Class<?>[] CLASS_BAISC_TYPES = new Class[] {Byte.class, Character.class, String.class, Integer.class, Long.class, Float.class, Double.class, Boolean.class};
	
	public TypeUtils() {
		throw new BaseException("can not instance " + getClass());
	}
    
	/**
	 * 布尔类型检查
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isBoolean(Object obj) {
		if(obj == null) {
			return false;
		}
		return isBoolean(obj.getClass());
	}
	
	/**
	 * 布尔类型检查
	 * 
	 * @param clazz
	 * @return
	 */
	public static boolean isBoolean(Class<?> clazz) {
		return isType(clazz, CLASS_BOOLEAN);
	}
	
	/**
	 * 数组类型检查
	 * 
	 * @param array
	 * @return
	 */
	public static boolean isArray(Object obj) {
		return isArray(obj.getClass());
	}

	/**
	 * 数组类型检查
	 * 
	 * @param clazz
	 * @return
	 */
	public static boolean isArray(Class<?> clazz) {
		return clazz.isArray();
	}

	/**
	 * 集合类型检查
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isCollection(Object obj) {
		return isCollection(obj.getClass());
	}
	
	/**
	 * 集合类型检查
	 * 
	 * @param clazz
	 * @return
	 */
	public static boolean isCollection(Class<?> clazz) {
		return isType(clazz, CLASS_COLLECTION);
	}
	
	/**
	 * List类型检查
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isList(Object obj) {
		return isList(obj.getClass());
	}
	
	/**
	 * List类型检查
	 * 
	 * @param clazz
	 * @return
	 */
	public static boolean isList(Class<?> clazz) {
		return isType(clazz, CLASS_LIST);
	}
	
	/**
	 * Set类型检查
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isSet(Object obj) {
		return isSet(obj.getClass());
	}
	
	/**
	 * Set类型检查
	 * 
	 * @param clazz
	 * @return
	 */
	public static boolean isSet(Class<?> clazz) {
		return isType(clazz, CLASS_SET);
	}
	
	/**
	 * Map类型检查
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isMap(Object obj) {
		return isMap(obj.getClass());
	}
	
	/**
	 * Map类型检查
	 * 
	 * @param clazz
	 * @return
	 */
	public static boolean isMap(Class<?> clazz) {
		return isType(clazz, CLASS_MAP);
	}
	
	/**
	 * 类型检查,也会检查继承或实现的类
	 * 
	 * @param clazz 检查类字节码
	 * @param type 类型字节码
	 * @return
	 */
	public static boolean isType(Class<?> clazz, Class<?> type) {
		return type.isAssignableFrom(clazz);
	}
	
	/**
	 * 判断基本类型包装类
	 * 
	 * @param clazz
	 * @return 基本类型返回true
	 */
	public static boolean isBasicType(Class<?> clazz) {
		for(Class<?> btc: CLASS_BAISC_TYPES) {
			if(isType(clazz, btc)) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 判断基本类型,该方式可用于基本类型
	 * 
	 * @param obj
	 * @return 基本类型返回true
	 */
	public static boolean isBasicType(Object obj) {
		return isBasicType(obj.getClass());
	}
	
	/**
	 * 获取最接近Object.class的父类对象
	 * 
	 * @param clazz
	 * @return
	 */
	public static Class<? extends Object> nearObjectSuper(Class<? extends Object> clazz) {
		if (clazz == CLASS_OBJECT)
			return CLASS_OBJECT;
		Class<?> sClass = clazz.getSuperclass();
		if (sClass == null)
			throw new BaseException("sClass == null");
		if (sClass == CLASS_OBJECT)
			return clazz;
		return nearObjectSuper(sClass);
	}
	
}
